package com.riaevolution.validators {
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	
	import mx.events.ValidationResultEvent;
	import mx.validators.Validator;

	[Bindable]

	/**
	 * Form validator utility. <br />
	 *
	 *
	 * <h3>Sample code</h3>
	 * <code>
	 *
	 * &lt;mx:Array id="validators"&gt;<br />
	 * 	&lt;mx:StringValidator id="studioNameValidator" source="{this.studioNameInput}" property="text" required="true"/&gt;<br />
	 * 	&lt;mx:EmailValidator id="emailValidator" source="{this.emailInput}" property="text" required="true"/&gt;<br />
	 * 	&lt;mx:PhoneNumberValidator id="phoneValidator" source="{this.phoneInput}" property="text" required="true"/&gt;<br />
	 * 	&lt;mx:StringValidator id="addValidator" source="{this.addressInput}" property="text" required="true"/&gt;<br />
	 * 	&lt;mx:ZipCodeValidator id="zipcodeValidator" source="{this.zipcodeInput}" property="text" required="true"/&gt;<br />
	 * &lt;/mx:Array&gt;<br /><br />
	 * &lt;validators:FormValidator id="formValidator" validators="{this.validators}"/&gt;<br />
	 *
	 * &lt;mx:TextInput id="studioNameInput" text="{this.studio.name}" <br />
	 * 	width="100%" change="formValidator.validateForm(event);"/&gt;<br /><br />
	 * </code>
	 */
	public class FormValidator extends EventDispatcher {
		public var formIsValid:Boolean=false;
		/**
		 * The list of mx.validators.Validator
		 *
		 * @see mx.validators.Validator
		 */
		public var validators:Array;
		/**
		 * @private
		 */
		private var focusedFormControl:DisplayObject;

		public function FormValidator(target:IEventDispatcher=null) {
			super(target);
		}

		/**
		 * Validate the current form
		 * @param event the dispatchin target. IE. button or form
		 */
		public function validateForm(event:Event):void {
			focusedFormControl=event.target as DisplayObject;
			formIsValid=true;

			for each (var validator:Validator in validators)
				validate(validator);
		}

		/**
		 * @private
		 */
		private function validate(validator:Validator):Boolean {
			var validatorSource:DisplayObject=validator.source as DisplayObject;
			var supressEvents:Boolean=validatorSource != focusedFormControl;
			var event:ValidationResultEvent=validator.validate(null, supressEvents)
			var currentControlIsValid:Boolean=event.type == ValidationResultEvent.VALID;

			formIsValid=formIsValid && currentControlIsValid;
			return currentControlIsValid;
		}
	}
}